﻿#pragma once
#include "yzrutil.h"
#include "DSP3D.h"
#include "RingBuffer.h"
#include "array/Arrays.h"
#include "array/Array.hpp"
#include "FFTConvolve.h"
#include "FIR.h"

namespace yzrilyzr_io{
	class InputStream;
}
namespace yzrilyzr_dsp{
	ECLASS(HRIR, public DSP3D){
	private:
	int32_t azLength=0;
	int32_t elLength=0;
	int32_t channels=0;
	int32_t cvLength=0;
	std::shared_ptr<yzrilyzr_array::SampleArray> hrirSrc=nullptr;
	std::shared_ptr<yzrilyzr_array::SampleArray> hrir=nullptr;
	FIR lFilter;
	FIR rFilter;
	u_sample_rate hrirSampleRate=0;
	public:
	HRIR(){}
	HRIR(std::shared_ptr<yzrilyzr_array::SampleArray> hrir, int32_t azLength, int32_t elLength, int32_t channels, int32_t cvLength, u_sample_rate hrirSampleRate);
	u_sample procDsp(u_sample v) override;
	void init(u_sample_rate sampleRate) override;
	void resetMemory() override;
	std::shared_ptr<DSP> cloneDSP() override;
	~HRIR();
	void cloneParam(DSP * obj1)override;
	void posChange()override;
	yzrilyzr_lang::String toString()const override;
	//
	u_index getHRIRIndex(int32_t az, int32_t el);
	int azimuthIndex(u_sample azimuth);
	int elevationIndex(u_sample elevation);
	void findNeighborsAndWeights(u_sample azimuth, u_sample elevation,
								 int aziIndices[2], int eleIndices[2],
								 u_sample aziWeights[2], u_sample eleWeights[2]);
	static u_sample pvaldeg(u_sample angle);//映射到[-90,270)
	static std::shared_ptr<HRIR> parseHRIR(yzrilyzr_io::InputStream & inp);
	};
}